package com.dataexa.ky.rest.mxgraph;

import com.dataexa.ky.core.mxgraph.util.mxXmlUtils;
import com.dataexa.ky.core.utils.dto.ResultDto;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
import org.w3c.dom.Document;

import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.util.Hashtable;
import java.util.Map;

/**
 * @author: tangshiwen
 * @create-date: 2025/8/26 上午9:22
 */
@Tag(name = "MxgraphResource", description = "DoDAF视图模块")
@Path("/mxgraph")
public class MxgraphRoundtripResource {
    private static int counter = 0;

    protected static Map<String, Document> diagrams = new Hashtable<>();

    @POST
    @Path("/roundtrip")
    @Operation(summary = "处理图表数据的双向同步", description = """
            核心逻辑：
            维护服务器端图表存储（内存中的diagrams映射）
            支持图表创建、更新和冲突检测（通过事务计数器TCN）
            初始图表XML定义在emptyDiagram变量中
            """)
    @Produces(MediaType.TEXT_XML)
    @Consumes(MediaType.TEXT_PLAIN)
    public ResultDto roundtrip(String input) {
        // 检查输入是否为空
        if (StringUtils.isBlank(input)) {
            return ResultDto.error("Input cannot be empty");
        }

        try {
            String xml = java.net.URLDecoder.decode(input, StandardCharsets.UTF_8);
            // 检查解码后的内容是否为空
            if (StringUtils.isBlank(xml)) {
                return ResultDto.error("Decoded input cannot be empty");
            }
            Document current = mxXmlUtils.parseXml(xml);
            // 检查解析后的文档是否为空
            if (current == null) {
                return ResultDto.error("Failed to parse XML input");
            }
            String tcn = current.getDocumentElement().getAttribute("tcn");
            String id = current.getDocumentElement().getAttribute("id");
            if (StringUtils.isBlank(id)) {
                id = String.valueOf(counter++);
                tcn = "0";
            } else {
                Document stored = diagrams.get(id);
                if (stored != null) {
                    String storedTcn = stored.getDocumentElement().getAttribute("tcn");

                    // 检查存储的TCN是否为有效数字
                    if (!StringUtils.isNumeric(storedTcn)) {
                        return ResultDto.error("Stored TCN is invalid");
                    }
                    // 检查传入的TCN是否为有效数字
                    if (!StringUtils.isNumeric(tcn)) {
                        return ResultDto.error("Input TCN must be a valid number");
                    }

                    if (Integer.parseInt(storedTcn) > Integer.parseInt(tcn)) {
                        return ResultDto.error("Diagram was changed by another user.");
                    } else {
                        tcn = String.valueOf(Integer.parseInt(tcn) + 1);
                    }
                }
            }

            current.getDocumentElement().setAttribute("tcn", tcn);
            current.getDocumentElement().setAttribute("id", id);
            diagrams.put(id, current);

            String result = MessageFormat.format("""
                    <result id="{0}" tcn="{1}"/>
                    """, id, tcn);
            return ResultDto.success(result);
        } catch (Exception e) {
            return ResultDto.error("Error processing request: " + e.getMessage());
        }
    }

    @GET
    @Path("/diagram")
    @Operation(summary = "获取图表数据", description = "根据ID获取图表数据，若ID不存在则返回空图表，若不提供ID则返回所有图表列表")
    @Produces(MediaType.TEXT_XML)
    public ResultDto getDiagram(@QueryParam("id") String id) {
        try {
            if (StringUtils.isBlank(id)) {
                StringBuilder sb = new StringBuilder();
                sb.append("<a href=\"?id=new\">Create diagram</a><br>");
                for (Document doc : diagrams.values()) {
                    String diagramId = doc.getDocumentElement().getAttribute("id");
                    sb.append("<a href=\"?id=").append(diagramId).append("\">Diagram ").append(diagramId).append("</a><br>");
                }
                return ResultDto.success(sb.toString());
            }

            Document diagram = diagrams.get(id);
            String xml;
            if (diagram != null) {
                xml = mxXmlUtils.getXml(diagram.getDocumentElement());
            } else {
                xml = emptyDiagram;
            }

            // 假设这里有一个读取模板文件的工具方法，实际使用时需要实现或替换
            // 若仅返回 XML 数据，可直接返回 xml 内容
            return ResultDto.success(xml);
        } catch (Exception e) {
            return ResultDto.error("Error processing request: " + e.getMessage());
        }
    }

    /**
     * 空图表
     */
    protected static String emptyDiagram = """
            <diagram><mxGraphModel>
            <root>
            <Workflow value="Diagram" id="0">
            <mxCell/>
            </Workflow>
            <Layer value="Default Layer" id="1">
            <mxCell parent="0"/>
            </Layer>
            <mxCell vertex="1" parent="1" value="Hello, World!">
            <mxGeometry x="120" y="90" width="80" height="40" as="geometry"/>
            </mxCell></root></mxGraphModel></diagram>""";
}
